package com.ada.base.security.service.impl;

import com.ada.base.security.CurrentUserContext;
import com.ada.base.security.entity.Role;
import com.ada.base.security.entity.RoleAuthority;
import com.ada.base.security.entity.UserRole;
import com.ada.base.security.entity.res.RoleRes;
import com.ada.base.security.exception.RoleAlreadyBoundUserException;
import com.ada.base.security.service.RoleService;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapperResultSetExtractor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;

@Service
@Transactional
public class RoleServiceImpl implements RoleService {
    private JdbcTemplate jdbcTemplate;

    public RoleServiceImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public List<RoleRes> roleList(long userId) {
        String sql = "select a.id id, a.code code, a.name name,b.userId userId from role a left join user_role b " +
                "on a.id=b.roleId and b.userId=?";
        return jdbcTemplate.query(sql,new Object[]{userId},new RowMapperResultSetExtractor<>(new BeanPropertyRowMapper<>(RoleRes.class), 1));
    }

    @Override
    public List<RoleRes> roleList(long userId, int type) {
        String sql = "select a.id id, a.code code, a.name name,b.userId userId from role a left join user_role b " +
                "on a.id=b.roleId and b.userId=? where a.type=? and a.clientId=?";
        return jdbcTemplate.query(sql,new Object[]{userId, type, CurrentUserContext.clientId()},new RowMapperResultSetExtractor<>(new BeanPropertyRowMapper<>(RoleRes.class), 1));
    }

    @Override
    public int add(Role role) {
        String sql = "insert into role(code, name, status, type,clientId) values(?,?,?,?,?)";
        return jdbcTemplate.update(sql, role.getCode(), role.getName(), role.getStatus().name(), role.getType(), CurrentUserContext.clientId());
    }

    @Override
    public void delete(Long roleId) {
        String query = "select id from user_role where roleId = ?";
        List<UserRole> userRoles = jdbcTemplate.query(query, new RowMapperResultSetExtractor<>(new BeanPropertyRowMapper<>(UserRole.class), 1));
        if (!CollectionUtils.isEmpty(userRoles))
            throw new RoleAlreadyBoundUserException("该角色已被绑定用户");
        String sql = "delete from role where id = ?";
        jdbcTemplate.update(sql, roleId);
        String sql2 = "delete from role_authority where roleId = ?";
        jdbcTemplate.update(sql2, roleId);
    }

    @Override
    public void allocAuthority(List<RoleAuthority> roleAuthorities) {
        if (CollectionUtils.isEmpty(roleAuthorities))
            return;
        String del = "delete from role_authority where roleId= ?";
        jdbcTemplate.update(del, roleAuthorities.get(0).getRoleId());
        String insert = "insert into role_authority(roleId, authorityId) values(?,?)";
        jdbcTemplate.batchUpdate(insert, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                RoleAuthority roleAuthority = roleAuthorities.get(i);
                ps.setLong(1, roleAuthority.getRoleId());
                ps.setLong(2, roleAuthority.getAuthorityId());
            }

            @Override
            public int getBatchSize() {
                return roleAuthorities.size();
            }
        });
    }
}
